﻿Imports System.Text.RegularExpressions

Public Class RssClient
    Private ReadOnly _rssUrl As String
    Private _control As Object

    Public Delegate Sub ItemsReceivedDelegate(ByVal client As RssClient, ByVal items As IList(Of FeedItem), ByVal control As Object)
    Public Event ItemsReceived As ItemsReceivedDelegate

    Public Sub New(ByVal rssUrl As String, ByVal control As Object)
        _rssUrl = rssUrl
        _control = control
    End Sub

    Public Sub LoadItems()
        Dim request = DirectCast(WebRequest.Create(_rssUrl), HttpWebRequest)
        Dim result = DirectCast(request.BeginGetResponse(AddressOf ResponseCallback, request), IAsyncResult)
    End Sub

    Private Sub ResponseCallback(ByVal result As IAsyncResult)
        Dim request = DirectCast(result.AsyncState, HttpWebRequest)

        Dim response As System.Net.WebResponse
        Try
            response = request.EndGetResponse(result)
        Catch generatedExceptionName As Exception
            RaiseEvent ItemsReceived(Me, Nothing, _control)
            Return
        End Try

        Dim stream = response.GetResponseStream()
        Dim reader = XmlReader.Create(stream)
        Dim items = New List(Of FeedItem)(50)

        Dim item As FeedItem = Nothing
        Dim pointerMoved = False

        While Not reader.EOF
            If pointerMoved Then
                pointerMoved = False
            Else
                If Not reader.Read() Then
                    Exit While
                End If
            End If

            Dim nodeName = reader.Name
            Dim nodeType = reader.NodeType

            If nodeName = "item" Then
                If nodeType = XmlNodeType.Element Then
                    item = New FeedItem()
                ElseIf nodeType = XmlNodeType.EndElement Then
                    If item IsNot Nothing Then
                        items.Add(item)
                        item = Nothing
                    End If
                End If

                Continue While
            End If

            If nodeType <> XmlNodeType.Element Then
                Continue While
            End If

            If nodeName.StartsWith("twitter:") Then
                Continue While
            End If

            If item Is Nothing Then
                Continue While
            End If

            Dim nodeValue As String

            Try
                reader.MoveToContent()
                nodeValue = reader.ReadElementContentAsString()
            Catch generatedExceptionName As Exception
                Continue While
            End Try

            ' we just moved internal pointer
            pointerMoved = True

            If nodeName = "title" Then
                item.Title = nodeValue
            ElseIf nodeName = "description" Then
                item.Description = Regex.Replace(nodeValue, "<(.|\n)*?>", String.Empty)
            ElseIf nodeName = "feedburner:origLink" Then
                item.Link = nodeValue
            ElseIf nodeName = "link" AndAlso item.Link Is Nothing Then
                item.Link = nodeValue
            ElseIf nodeName = "pubDate" Then
                If Not String.IsNullOrEmpty(nodeValue) Then
                    item.PublishDate = DateTime.Parse(nodeValue)
                End If
            ElseIf nodeName = "category" Then
                item.Categories.Add(nodeValue)
            End If
        End While

        RaiseEvent ItemsReceived(Me, items, _control)
    End Sub
End Class

